/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#ifndef DEVMON_UTILS_H
#define DEVMON_UTILS_H

#include <chrono>
#include <cstdint>
#include <mc/dict.h>
#include <mc/fmt/format_v.h>
#include <mc/log.h>
#include <optional>

#define BUILD_TYPE_DEBUG   1
#define BUILD_TYPE_RELEASE 2
#define BUILD_TYPE_DT      3

namespace devmon {

enum class BuildType { Debug, Release, Dt, Unknown };

// 前向声明
struct unit;

class utils {
public:
    static BuildType get_build_type();
    static bool      is_release_build() {
        return get_build_type() == BuildType::Release;
    }
    static uint64_t get_sys_ms() {
        auto now      = std::chrono::system_clock::now();
        auto duration = now.time_since_epoch();
        auto millis   = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
        return static_cast<uint64_t>(millis);
    }

    static std::string get_connector_position(const mc::dict& connector) {
        // 使用GroupPosition而不是Position，因为GroupPosition是对象组的实际位置
        if (!connector.contains("GroupPosition")) {
            return "";
        }
        auto v = connector["GroupPosition"];
        if (v.is_integer()) {
            std::string pos = mc::format_v("%02X", v.as<int>());
            if (pos.size() % 2 != 0) {
                // 如果长度为奇数，则补齐一个0
                pos = "0" + pos;
            }
            return pos;
        }
        return v.as<std::string>();
    }

    /**
     * 从连接器中安全地获取 unit 信息
     * @param connector 连接器字典
     * @return 成功时返回 unit 对象，失败时返回 std::nullopt
     */
    static std::optional<unit> get_connector_unit(const mc::dict& connector);
};
} // namespace devmon

#endif // DEVMON_UTILS_H